<template>
  <el-form label-width="120px" ref="FormRef" :model="spuInfo" :rules="rules">
    <!-- spu名称 -->
    <el-form-item label="SPU名称" prop="spuName">
      <el-input placeholder="请输入SPU名称" v-model="spuInfo.spuName"></el-input>
    </el-form-item>

    <!-- spu品牌 -->
    <el-form-item label="SPU品牌" prop="tmId">
      <el-select placeholder="请选择" v-model="spuInfo.tmId">
        <el-option :value="(tm.id as number)" :label="tm.tmName" v-for="tm in trademarkList" :key="tm.id"></el-option>
      </el-select>
    </el-form-item>
    <!-- spu描述 -->
    <el-form-item label="SPU描述" prop="description">
      <el-input type="textarea" placeholder="请输入SPU描述信息" rows="4" v-model="spuInfo.description"></el-input>
    </el-form-item>
    <!-- spu图片 -->
    <el-form-item label="SPU图片" prop="spuImageList">
      <el-upload
        v-model:file-list="(spuInfo.spuImageList as any)"
        :action="`${BaseUrl}//admin/product/fileUpload`"
        list-type="picture-card"
        :on-preview="handlePictureCardPreview"
        :on-remove="handleRemove"
        :on-success="handleSuccess"
      >
        <el-icon><Plus /></el-icon>
      </el-upload>
      <el-dialog v-model="dialogVisible">
        <img w-full :src="dialogImageUrl" alt="Preview Image" />
      </el-dialog>
    </el-form-item>
    <!-- 销售属性 -->
    <el-form-item label="销售属性" prop="spuSaleAttrList">
      <el-select placeholder="请选择" v-model="saleAttrIdName">
        <el-option :value="base.id + '_' + base.name" :label="base.name" v-for="base in unSelectedSaleAttrList" :key="base.id"></el-option>
      </el-select>
      <!-- 小按钮 -->
      <el-button type="primary" :icon="Plus" @click="addSaleAttr">添加销售属性</el-button>
      <!-- 小表格 -->
      <el-table row-key="id" :data="spuInfo.spuSaleAttrList" stripe border style="width: 100%">
        <!-- 序号 -->
        <el-table-column align="center" type="index" label="序号" width="80" />
        <!-- 属性名 -->
        <el-table-column prop="saleAttrName" label="属性名" width="150" />
        <!-- 属性值名称列表 -->
        <el-table-column prop="spuSaleAttrValueList" label="属性值名称列表">
          <template v-slot="{ row, $index }">
            <el-tag
              class="mx-1"
              type="success"
              v-for="(val, index) in row.spuSaleAttrValueList"
              :key="val.id"
              closable
              :disable-transitions="false"
              @close="row.spuSaleAttrValueList.splice(index, 1)"
              style="margin-right: 5px"
              >{{ val.saleAttrValueName }}</el-tag
            >
            <el-input
              v-if="row.isShowEdit"
              :ref="(input:any)=>inputRefs[$index] = input"
              v-model="saleAttrValueName"
              class="ml-1 w-20"
              size="small"
              @keyup.enter="toView(row)"
              @blur="toView(row)"
              style="width: 100px"
            />
            <el-button v-else class="button-new-tag ml-1" size="small" @click="toEdit(row, $index)" :icon="Plus"></el-button>
          </template>
        </el-table-column>
        <!-- 操作-->
        <el-table-column label="操作">
          <template #default="{ row, $index }">
            <el-button size="default" :icon="Delete" type="danger" @click="deleteClick($index)"></el-button>
          </template>
        </el-table-column>
      </el-table>
    </el-form-item>
    <!-- 两个按钮 -->
    <el-form-item>
      <el-button type="primary" size="default" @click="saveClick">保存</el-button>
      <el-button size="default" @click="emits('setShowStatus', ShowStatus.SPU_LIST)">取消</el-button>
    </el-form-item>
  </el-form>
</template>
<script lang="ts">
export default {
  name: "SpuForm",
};
</script>
<script lang="ts" setup>
import { ref, reactive, onMounted, nextTick, computed } from "vue";
// 引入标识数据
import { ShowStatus } from "./types";
// 引入需要的icon的图标
import { Plus, Delete } from "@element-plus/icons-vue";
// 引入上传图片需要的类型
import { type UploadProps, type UploadUserFile, type UploadFile, type UploadFiles, ElMessage } from "element-plus";
import type { BaseSaleAttrListModel, SpuModel, SpuSaleAttrModel } from "@/api/product/model/spuModel";
import type { TrademarkListModel } from "@/api/product/model/trademarkModel";
import { reqGetTrademarkListAll } from "@/api/product/trademark";
import { reqGetBaseSaleAttrList, reqGetSpuInfoImageList, reqGetSpuInfoSaleAttrList, reqAddOrUpdate } from "@/api/product/spu";
// 引入规则类型
import type { FormInstance, FormRules } from "element-plus";
import Item from "@/layout/components/Sidebar/Item";
import useCategoryStore from "@/stores/category";
// 用于接受父级组件的自定义事件
const emits = defineEmits(["setShowStatus"]);
// 定义基础的路径
const BaseUrl = import.meta.env.VITE_API_URL;

// 定义上传图片的回调

const dialogImageUrl = ref("");
const dialogVisible = ref(false);

const handleRemove: UploadProps["onRemove"] = (uploadFile, fileList: UploadFiles) => {
  spuInfo.spuImageList = fileList as any;
};

const handlePictureCardPreview: UploadProps["onPreview"] = (uploadFile) => {
  dialogImageUrl.value = uploadFile.url!;
  dialogVisible.value = true;
};

const handleSuccess: UploadProps["onSuccess"] = (res, file: UploadFile, fileList: UploadFiles) => {
  // 需要做的事 ：保存上传成功的图片
  spuInfo.spuImageList = fileList as any;
};

// 接收父级组件传递过来的spu对象数据
const props = defineProps<{ currentSpuInfo: SpuModel }>();
// 定义一个spuInfo对象数据
const spuInfo = reactive<SpuModel>(props.currentSpuInfo);
// 定义所有品牌列表数据
const trademarkList = ref<TrademarkListModel>([]);
// 定义获取所有的基础销售属性列表数据
const baseSaleAttrList = ref<BaseSaleAttrListModel>([]);

// 组件加载后获取的品牌列表数据
onMounted(async () => {
  trademarkList.value = await reqGetTrademarkListAll();
});
// 组件加载后获取所有的基础销售属性列表数据
onMounted(async () => {
  baseSaleAttrList.value = await reqGetBaseSaleAttrList();
});
// 组件加载后获取spu下所有的销售属性列表数据
onMounted(async () => {
  spuInfo.spuSaleAttrList = await reqGetSpuInfoSaleAttrList(spuInfo.id as number);
});
// 组件加载获取spu下所有的图片列表数据
onMounted(async () => {
  const id = spuInfo.id as number;
  if (!id) return;
  const spuImageListss = await reqGetSpuInfoImageList(id);
  spuInfo.spuImageList = spuImageListss.map((item) => ({
    ...item,
    name: item.imgName,
    url: item.imgUrl,
  }));
});

const saleAttrIdName = ref<string>("");
// 用来收集文本框dom对象的数组
const inputRefs = ref<HTMLInputElement[]>([]);
// 用来收集销售属性录入的数据
const saleAttrValueName = ref<string>("");

// 查看模式
const toView = (row: SpuSaleAttrModel) => {
  // 判断用户输入的数据是否有效
  if (!saleAttrValueName.value || !saleAttrValueName.value.trim()) {
    ElMessage.warning("请输入有效的数据");
    saleAttrValueName.value = "";
    row.isShowEdit = false;
    return;
  }
  // 判断用户输入的数据和之前存在的数据是否相同
  const isRepeat = row.spuSaleAttrValueList.some((item) => item.saleAttrValueName == saleAttrValueName.value);
  if (isRepeat) {
    ElMessage.warning("数据有重复的");
  } else {
    // 吧这个数据添加到属性值对象数组中
    row.spuSaleAttrValueList.push({
      baseSaleAttrId: row.baseSaleAttrId,
      saleAttrValueName: saleAttrValueName.value,
    });
  }
  // 查看模式
  saleAttrValueName.value = "";
  row.isShowEdit = false;
};
// 编辑模式
const toEdit = (row: SpuSaleAttrModel, index: number) => {
  row.isShowEdit = true;
  // 自动获取焦点
  nextTick(() => {
    inputRefs.value[index].focus();
  });
};
// 定义form表单的dom对象
const FormRef = ref<FormInstance>();
// 定义验证规则
const rules = reactive<FormRules>({
  spuName: [{ required: true, message: "必须输入spuName", trigger: "blur" }],
  tmId: [{ required: true, message: "必须输入tmId", trigger: "change" }],
  description: [{ required: true, message: "必须输入描述信息", trigger: "blur" }],
  spuImageList: [{ required: true, message: "必须输入上传一张图片", trigger: "change", type: "array" }],
  spuSaleAttrList: [{ required: true, message: "必须输入添加一个销售属性", trigger: "change", type: "array" }],
});
//计算出来一个新数组  没有被选中的销售属性对象的数组数据
const unSelectedSaleAttrList = computed(() => {
  return baseSaleAttrList.value.filter((bsa) => !spuInfo.spuSaleAttrList.some((sa) => sa.saleAttrName == bsa.name));
});

// 计算出来一个动态的文字提示信息
const saleAttrText = computed(() => {
  const { length } = unSelectedSaleAttrList.value;
  return length > 0 ? `还有${length}个未选择` : "没有了";
});

// 添加销售属性操作
const addSaleAttr = () => {
  // 把id个名字的数据中的_切掉
  const [id, name] = saleAttrIdName.value.split("_");
  // 吧id个name组成一个对象  方法在spuInfo对象的spuSaleAttrList数组中
  spuInfo.spuSaleAttrList.push({
    baseSaleAttrId: +id,
    saleAttrName: name,
    spuSaleAttrValueList: [],
  });
  saleAttrIdName.value = "";
};
// 点击保存的回调函数
const saveClick = async () => {
  await FormRef.value?.validate();

  // 过滤销售属性数据
  spuInfo.spuSaleAttrList = spuInfo.spuSaleAttrList.filter((item) => {
    // 判断里面的属性值数组是否有数据
    if (item.spuSaleAttrValueList.length === 0) return false;
    delete item.isShowEdit;
    return true;
  });

  // 过滤图片的数据
  spuInfo.spuImageList = spuInfo.spuImageList.map((item) => ({
    imgName: item.name as string,
    imgUrl: (item.response ? item.response.data : item.url) as string,
    spuId: spuInfo.id as number,
  }));

  // 二次验证
  if (spuInfo.spuSaleAttrList.length === 0) {
    ElMessage.warning("必须添加一个spu的销售属性");
    return;
  }
  // 更新三级分类的id
  spuInfo.category3Id = useCategoryStore().getCategory3Id as number;
  try {
    // 调用接口  发送请求
    await reqAddOrUpdate(spuInfo);
    ElMessage.success("保成功");
  } catch (error) {
    console.log("出错了");
  }
  // 关闭界面  回到列表页   数据重置 刷新
  emits("setShowStatus", ShowStatus.SPU_LIST);
};

// 定义删除的回调函数
const deleteClick = (index: number) => {
  spuInfo.spuSaleAttrList.splice(index, 1);
};
</script>
<style scoped></style>
